use hime_redist::parsers::{Parser,lrk::{LRkParser,LRkAutomaton}};
use hime_redist::text::{Text};
use hime_redist::symbols::{Symbol,SemanticBody};
use hime_redist::result::ParseResult;
use hime_redist::ast::{AstImpl,Ast,AstNode};

use crate::HimeLex;

const PARSER_AUTOMATON: &[u8] = include_bytes!("MyGrammarParser.bin");

const TERMINALS: &[Symbol] = &[
    Symbol { id: 0x0001, name: "ε" },
    Symbol { id: 0x0002, name: "$" },
    Symbol { id: 0x0003, name: "LIT_CHAR" },
    Symbol { id: 0x0004, name: "WHITE_SPACE" },
    Symbol { id: 0x0005, name: "SEPARATOR" }];

const VARIABLES: &[Symbol] = &[
    Symbol { id: 0x0005, name: "char" },
    Symbol { id: 0x0006, name: "__VAxiom" }];

const VIRTUALS: &[Symbol] = &[];

pub fn hime_parse(code_string:&str) {
    let mut lex = HimeLex::new(code_string);
    let mut my_actions = |_index: usize, _head: Symbol, _body: &dyn SemanticBody| ();
    
    let mut result = ParseResult::new(TERMINALS, VARIABLES, VIRTUALS, Text::new(code_string));
    {
        let data = result.get_parsing_data();
        let automaton = LRkAutomaton::new(PARSER_AUTOMATON);
        let mut parser = LRkParser::new(&mut lex, automaton,data.2, &mut my_actions);
        parser.parse();
    }
    let ast = result.get_ast();
    let errors = result.get_errors();
    println!("succ:{}",result.is_success());
    println!("text:{}",result.get_input().len());
    //print(ast.get_root(), vec![]);
    println!("count:{}",errors.get_count());
}

fn print<'a>(node: AstNode<'a>, crossings: Vec<bool>) {
    let mut i = 0;
    if !crossings.is_empty() {
        while i < crossings.len() - 1 {
            print!("{:}", if crossings[i] { "|   " } else { "    " });
            i += 1;
        }
        print!("+-> ");
    }
    println!("{:}", node);
    i = 0;
    let children = node.children();
    while i < children.len() {
        let mut child_crossings = crossings.clone();
        child_crossings.push(i < children.len() - 1);
        print(children.at(i), child_crossings);
        i += 1;
    }
}

#[test]
pub(crate) fn test_hime_parser() {
    hime_parse("_");
}